package com.zzz.bayer

import java.io.DataOutputStream
import java.io.File

object BmpHelper {

    private fun create1bitColorTable(): ByteArray {
        val byteArray = ByteArray(2 * 4)
        for (i in arrayOf(0, 255)) {
            byteArray[0 + 4 * i] = i.toByte()//Blue
            byteArray[1 + 4 * i] = i.toByte()//Green
            byteArray[2 + 4 * i] = i.toByte()//Red
            byteArray[3 + 4 * i] = i.toByte()//保留位
        }
        return byteArray
    }

    private fun create8bitColorTable(): ByteArray {
        val byteArray = ByteArray(256 * 4)
        for (i in 0..255) {
            byteArray[0 + 4 * i] = i.toByte()//Blue
            byteArray[1 + 4 * i] = i.toByte()//Green
            byteArray[2 + 4 * i] = i.toByte()//Red
            byteArray[3 + 4 * i] = i.toByte()//保留位
        }
        return byteArray
    }


    /**
     * 小端模式int转byteArray
     */
    private fun changeByte(value: Int): ByteArray {
        val src = ByteArray(4)
        src[3] = ((value shr 24) and 0xff).toByte()
        src[2] = ((value shr 16) and 0xff).toByte()
        src[1] = ((value shr 8) and 0xff).toByte()
        src[0] = (value and 0xff).toByte()
        return src
    }

    fun convert1bit(filePath: String, width: Int, height: Int, data: ByteArray) {
        val colorTable = create1bitColorTable()
        //文件头
        val bfType = 0x424d //位图文件类型
        val bfSize = 54 + colorTable.size + data.size //bmp文件大小
        val bfReserved1 = 0 //位图文件保留字
        val bfReserved2 = 0 //位图文件保留字
        val bfOffBits = 54 + colorTable.size //文件头开始到位图实际数据之间的字节偏移
        //信息头
        val biSize = 40 //信息头所需要的字节数
        val biWidth = width
        val biHeight = -height//位图数据从下往上，从右向左
        val biPlanes = 1 //目标设备的级别，必须是1
        val bitBitCount = 1 //每个像素所需的位数，可以是1，2，4，8，16，24
        val biCompression = 0 ///位图压缩类型
        val biSizeImage = width * height
        val biXPelsPerMeter = 0 //x方向分辨率
        val biYPelsPerMeter = 0 //y方向分辨率
        val biClrUsed = 0  //引用所有调色板项
        val biClrImportant = 0 //重要颜色数，如果为0，则表示所有颜色都是重要的

        File(filePath).outputStream().use {
            DataOutputStream(it).use { dos ->
                //文件头
                dos.writeShort(bfType)
                dos.write(changeByte(bfSize), 0, 4)
                dos.write(changeByte(bfReserved1), 0, 2)
                dos.write(changeByte(bfReserved2), 0, 2)
                dos.write(changeByte(bfOffBits), 0, 4)
                //信息头
                dos.write(changeByte(biSize), 0, 4)
                dos.write(changeByte(biWidth), 0, 4)
                dos.write(changeByte(biHeight), 0, 4)
                dos.write(changeByte(biPlanes), 0, 2)
                dos.write(changeByte(bitBitCount), 0, 2)
                dos.write(changeByte(biCompression), 0, 4)
                dos.write(changeByte(biSizeImage), 0, 4)
                dos.write(changeByte(biXPelsPerMeter), 0, 4)
                dos.write(changeByte(biYPelsPerMeter), 0, 4)
                dos.write(changeByte(biClrUsed), 0, 4)
                dos.write(changeByte(biClrImportant), 0, 4)
                //调色板
                dos.write(colorTable)
                //图片数据
                dos.write(data)
                dos.flush()
            }
        }
    }

    fun convert8bit(filePath: String, width: Int, height: Int, data: ByteArray) {
        val colorTable = create8bitColorTable()
        //文件头
        val bfType = 0x424d //位图文件类型
        val bfSize = 54 + colorTable.size + data.size //bmp文件大小
        val bfReserved1 = 0 //位图文件保留字
        val bfReserved2 = 0 //位图文件保留字
        val bfOffBits = 54 + colorTable.size //文件头开始到位图实际数据之间的字节偏移
        //信息头
        val biSize = 40 //信息头所需要的字节数
        val biWidth = width
        val biHeight = -height//位图数据从下往上，从右向左
        val biPlanes = 1 //目标设备的级别，必须是1
        val bitBitCount = 8 //每个像素所需的位数，可以是1，2，4，8，16，24
        val biCompression = 0 ///位图压缩类型
        val biSizeImage = width * height
        val biXPelsPerMeter = 0 //x方向分辨率
        val biYPelsPerMeter = 0 //y方向分辨率
        val biClrUsed = 0  //引用所有调色板项
        val biClrImportant = 0 //重要颜色数，如果为0，则表示所有颜色都是重要的

        File(filePath).outputStream().use {
            DataOutputStream(it).use { dos ->
                //文件头
                dos.writeShort(bfType)
                dos.write(changeByte(bfSize), 0, 4)
                dos.write(changeByte(bfReserved1), 0, 2)
                dos.write(changeByte(bfReserved2), 0, 2)
                dos.write(changeByte(bfOffBits), 0, 4)
                //信息头
                dos.write(changeByte(biSize), 0, 4)
                dos.write(changeByte(biWidth), 0, 4)
                dos.write(changeByte(biHeight), 0, 4)
                dos.write(changeByte(biPlanes), 0, 2)
                dos.write(changeByte(bitBitCount), 0, 2)
                dos.write(changeByte(biCompression), 0, 4)
                dos.write(changeByte(biSizeImage), 0, 4)
                dos.write(changeByte(biXPelsPerMeter), 0, 4)
                dos.write(changeByte(biYPelsPerMeter), 0, 4)
                dos.write(changeByte(biClrUsed), 0, 4)
                dos.write(changeByte(biClrImportant), 0, 4)
                //调色板
                dos.write(colorTable)
                //图片数据
                dos.write(data)
                dos.flush()
            }
        }
    }

}